package cn.dansj.common.utils.thread;

import cn.dansj.common.utils.spring.request.RequestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;

public class GlobalThreadPool {
    // 核心配置参数
    private static final int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors();
    private static final int MAX_POOL_SIZE = 200;
    private static final int QUEUE_CAPACITY = 1000;
    private static final long KEEP_ALIVE_TIME = 30L;
    private static final Logger logger = LoggerFactory.getLogger(GlobalThreadPool.class);

    // 自定义线程工厂
    private static final ThreadFactory THREAD_FACTORY = new ThreadFactory() {
        private final AtomicLong threadCount = new AtomicLong(1);

        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(r);
            thread.setName("global-pool-" + threadCount.getAndIncrement());
            thread.setUncaughtExceptionHandler((t, e) -> {
                logger.error("线程 [{}] 发生未捕获异常: ", t.getName(), e);
            });
            return thread;
        }
    };

    // 自定义拒绝策略
    private static final RejectedExecutionHandler REJECTION_HANDLER = (runnable, executor) -> {
        // 记录日志和指标
        logger.error("任务被拒绝: {}", runnable);
        // 可选的降级策略
        if (!executor.isShutdown()) {
            try {
                // 尝试重新放入队列（阻塞一段时间）
                boolean offer = executor.getQueue().offer(runnable, 500, TimeUnit.MILLISECONDS);
                if (!offer) {
                    runDegradedExecution(runnable);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                logger.warn("重试提交任务被中断: {}", e.getMessage());
            }
        }
    };

    // 全局线程池实例
    private static final ExecutorService GLOBAL_POOL = new ThreadPoolExecutor(
            CORE_POOL_SIZE,
            MAX_POOL_SIZE,
            KEEP_ALIVE_TIME,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(QUEUE_CAPACITY),
            THREAD_FACTORY,
            REJECTION_HANDLER
    );

    // 获取全局线程池
    public static ExecutorService getPool() {
        return GLOBAL_POOL;
    }

    // 安全关闭钩子
    static {
        Runtime.getRuntime().addShutdownHook(new Thread(GlobalThreadPool::shutdownAndAwaitTermination));
    }

    // 优雅关闭方法
    public static void shutdownAndAwaitTermination() {
        GLOBAL_POOL.shutdown(); // 不再接受新任务
        try {
            // 等待现有任务完成
            if (!GLOBAL_POOL.awaitTermination(30, TimeUnit.SECONDS)) {
                // 强制取消正在执行的任务
                GLOBAL_POOL.shutdownNow();
                // 再次等待任务响应取消
                if (!GLOBAL_POOL.awaitTermination(30, TimeUnit.SECONDS)) {
                    logger.error("线程池未能完全终止");
                }
            }
        } catch (InterruptedException ie) {
            // 重新取消
            GLOBAL_POOL.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }

    // 降级执行策略
    private static void runDegradedExecution(Runnable task) {
        try {
            // 在当前线程执行（简单降级）
            logger.error("重新提交失败, 执行降级处理：当前线程运行任务");
            task.run();
        } catch (Throwable t) {
            logger.error("降级执行失败: {}", t.getMessage());
        }
    }

    // 提交任务方法
    public static Future<?> submit(Runnable task) {
        return GLOBAL_POOL.submit(RequestUtils.wrap(task));
    }

    public static void execute(Runnable task) {
        GLOBAL_POOL.execute(RequestUtils.wrap(task));
    }
}